

#include <idt.h>
#include <gdt.h>
#include <debug.h>

f_isr isr_table[256];

void default_isr(int vector, int code);

idt_entry_t idt[256];
idt_ptr_t ip;

void init_idt(void)
{
	int i;
	extern void (*__isr_stub_table[256])(void);
	
	//extern void (*__dummy_isr)(void);
	
	ip.limit = (sizeof(idt_entry_t) * 256) - 1;
	ip.base = (dword)&idt;
	
	for (i = 0; i < 256; i++)
	{
		idt_set_entry(i, (unsigned long)__isr_stub_table[i], SEL_CODE, (IDT_FLAGS | IDT_FLAGS_RING0));
		//idt_set_entry(i, (dword)__isr_stub_table[i], SEL_CODE, 0x8E);
		idt_set_isr(i, default_isr);
	}
	
	idt_install();
	
	debugf("IDT: Installed @ 0x%08x\n", &idt);
	debugf("IDT: Pointer @ 0x%08x\n", &ip);
}

f_isr idt_set_isr(int index, f_isr isr)
{
	f_isr old_isr;
	old_isr = isr_table[index];
	isr_table[index] = isr;
	return old_isr;
}

void idt_set_entry(int index, dword base, word selector, byte flags)
{
	idt[index].base_lo = (base & 0xFFFF);
	idt[index].base_hi = ((base >> 16) & 0xFFFF);
	
	idt[index].selector = selector;
	idt[index].zero = 0;
	idt[index].flags = flags;
}

idt_entry_t idt_get_entry(int index)
{
	return idt[index];
}

void idt_install(void)
{	
	__idt_install();
	//asm("lidt (%0)" : : "rim" (ip));
}

void default_isr(int vector, int code)
{
	extern dword t;
	debugf("ISR #%d called with code (%d)! t=%d\n", vector, code, t++);
	pause();
	//for (;;) {}
}
